package indi.jp.project.base.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import indi.jp.project.base.entity.Employee;
import indi.jp.project.base.entity.EmployeeCert;
import indi.jp.project.base.entity.EmployeeTemp;
import indi.jp.project.base.service.EmployeeService;
import indi.jp.project.core.dao.BaseDao;
import indi.jp.project.core.entity.JsonResult;
import indi.jp.project.core.entity.Role;
import indi.jp.project.core.entity.User;
import indi.jp.project.core.service.RoleService;
import indi.jp.project.core.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.sql.SQLException;
import java.util.*;

@Service
public class EmployeeServiceImpl implements EmployeeService {

    private BaseDao baseDao;

    public EmployeeServiceImpl(BaseDao baseDao) {
        this.baseDao = baseDao;
    }

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Override
    public Map<String, Object> queryGrid(Employee entity) throws SQLException {
        Map<String, Object> map = new HashMap<>();
        List<Employee> list = baseDao.queryList("employeeMapper.queryList", entity);
        int count = baseDao.queryCount("employeeMapper.queryCount", entity);
        map.put("grid", list);
        map.put("total", count);
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult save(Employee entity) throws SQLException {
        User user = new User();
        user.setUsername(entity.getUsername());
        user.setNickname(entity.getName());
        if(entity.getResignDate() != null){
            user.setState(9);
            entity.setState(9);
        } else {
            user.setState(0);
            entity.setState(0);
        }

        if ("".equals(entity.getId())) {
            String id = UUID.randomUUID().toString();
            user.setId(id);
            entity.setId(id);
            baseDao.insert("employeeMapper.save", entity);
            userService.save(user);
        } else {
            user.setId(entity.getId());
            baseDao.update("employeeMapper.edit", entity);
            userService.edit(user);
            baseDao.delete("employeeMapper.deleteEmployeeCert", entity.getId());
        }
        List<EmployeeCert> certs = new ArrayList<>();
        certs.addAll(entity.getEduCerts());
        certs.addAll(entity.getQuaCerts());
        certs.addAll(entity.getProCerts());
        if(certs.size() > 0){
            certs.forEach(employeeCert -> {
                employeeCert.setsId(entity.getId());
                employeeCert.setCreateBy(entity.getCreateBy());
            });
            baseDao.insert("employeeMapper.saveEmployeeCert", certs);
        }
        return JsonResult.success("");
    }

    @Override
    @Transactional(rollbackFor = SQLException.class)
    public int deleteById(String id) throws SQLException {
        int effectRow = baseDao.deleteById("employeeMapper.deleteById", id);
        if (effectRow > 0) {
            userService.deleteById(id);
        }
        return effectRow;
    }

    @Override
    public Employee findEmployeeById(String id) throws SQLException {
        Employee employee = (Employee) baseDao.findById("employeeMapper.findEmployeeById", id);
        List<EmployeeCert> certs = baseDao.queryList("employeeMapper.queryEmployeeCert", id);
        List<EmployeeCert> eduCert = new ArrayList<>();
        List<EmployeeCert> quaCert = new ArrayList<>();
        List<EmployeeCert> proCert = new ArrayList<>();
        if(certs != null && certs.size() > 0){
            certs.forEach(employeeCert -> {
                if(employeeCert.getCategory() == 0){
                    eduCert.add(employeeCert);
                } else if(employeeCert.getCategory() == 1) {
                    quaCert.add(employeeCert);
                } else {
                    proCert.add(employeeCert);
                }
            });
            employee.setEduCerts(eduCert);
            employee.setQuaCerts(quaCert);
            employee.setProCerts(proCert);
        }
        return employee;
    }

    @Override
    public Map<String, Object> queryTempGrid(EmployeeTemp entity) throws SQLException {
        Map<String, Object> map = new HashMap<>();
        List<Employee> list = baseDao.queryList("employeeMapper.queryTempList", entity);
        int count = baseDao.queryCount("employeeMapper.queryTempCount", entity);
        map.put("grid", list);
        map.put("total", count);
        return map;
    }

    @Override
    @Transactional(rollbackFor = SQLException.class)
    public void batchInsertTemp(List<EmployeeTemp> list) throws SQLException {
        List<EmployeeTemp> tempList = new LinkedList<>();
        for (int i = 0; i < list.size(); i++) {
            tempList.add(list.get(i));
            if (i % 200 == 0) {
                baseDao.insert("employeeMapper.batchInsertTemp", tempList);
                tempList = new LinkedList<>();
            }
        }
        baseDao.insert("employeeMapper.batchInsertTemp", tempList);
    }

    @Override
    @Transactional(rollbackFor = SQLException.class)
    public int doExecute() throws SQLException {
        List<Employee> list = baseDao.queryList("employeeMapper.queryTempEmployee", "");
        if(list == null || list.size() == 0){
            return 0;
        }

        List<Employee> employees = new ArrayList<>();
        List<User> users = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            String id = UUID.randomUUID().toString();
            String employeeNo = list.get(i).getEmployeeNo();
            String name = list.get(i).getName();
            int gender = list.get(i).getGender();
            String phone = list.get(i).getPhone();
            String departmentId = list.get(i).getDepartmentId();
            String departmentCode = list.get(i).getDepartmentCode();
            String departmentName = list.get(i).getDepartmentName();
            String kindCode = list.get(i).getKindCode();
            String kindName = list.get(i).getKindName();
            String createBy = list.get(i).getCreateBy();

            Employee employee = new Employee();
            employee.setId(id);
            employee.setUsername(employeeNo);
            employee.setEmployeeNo(employeeNo);
            employee.setName(name);
            employee.setGender(gender);
            employee.setPhone(phone);
            employee.setDepartmentId(departmentId);
            employee.setDepartmentCode(departmentCode);
            employee.setDepartmentName(departmentName);
            employee.setKindCode(kindCode);
            employee.setKindName(kindName);
            employee.setCreateBy(createBy);
            employees.add(employee);

            User user = new User();
            user.setId(id);
            user.setUsername(employeeNo);
            user.setNickname(name);
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            String password = encoder.encode("123456");
            user.setPassword(password);
            users.add(user);
        }
        baseDao.insert("employeeMapper.batchInsertEmployee", employees);
        userService.batchInsertUser(users);
        return baseDao.update("employeeMapper.batchUpdateTemp", list);
    }

    @Override
    public Employee getEmployeeInfo(Employee entity) throws SQLException {
        Employee employee;
        if("admin".equals(entity.getUsername())){
            employee = entity;
            employee.setEmployeeNo("admin");
            employee.setName("系统管理员");
            employee.setDepartmentId("");
            employee.setDepartmentCode("");
            employee.setDepartmentName("无");
        } else {
            employee = (Employee) baseDao.findByObject("employeeMapper.getEmployeeInfo", entity);
        }
        List<Role> roles = roleService.queryRolesByUsername(entity.getUsername());
        if(roles != null && roles.size() > 0){
            employee.setRoles(roles);
        }
        return employee;
    }

    @Override
    public Map<String, Object> getProcessEmployee(Map<String, Object> params) throws SQLException {
        Map<String, Object> map = new HashMap<>();
        List<Employee> list = baseDao.queryList("employeeMapper.queryProcessEmployeeList", params);
        int count = baseDao.queryCount("employeeMapper.queryProcessEmployeeCount", params);
        map.put("grid", list);
        map.put("total", count);
        return map;
    }

    @Override
    public void dealCert() throws SQLException {
        List<Map<String, String>> list = baseDao.queryList("employeeMapper.queryUserCertTemp", "");
        List<EmployeeCert> certs = new ArrayList<>();
        for (Map<String, String> map : list){
            String id = map.get("id");
            String eduStr = map.get("eduCerts");
            String quaStr = map.get("quaCerts");
            String createBy = map.get("createBy");
            if(eduStr != null && !StringUtils.isEmpty(eduStr)){
                JSONArray ja = JSONArray.parseArray(eduStr);
                for(int i = 0; i<ja.size();i++){
                    JSONObject jo = ja.getJSONObject(i);
                    EmployeeCert cert = new EmployeeCert();
                    cert.setsId(id);
                    cert.setCategory(0);
                    cert.setFileName(jo.getString("name"));
                    cert.setStorageName(jo.getString("url"));
                    cert.setCreateBy(createBy);
                    certs.add(cert);
                }
            }
            if(quaStr != null && !StringUtils.isEmpty(quaStr)){
                JSONArray ja = JSONArray.parseArray(quaStr);
                for(int i = 0; i<ja.size();i++){
                    JSONObject jo = ja.getJSONObject(i);
                    EmployeeCert cert = new EmployeeCert();
                    cert.setsId(id);
                    cert.setCategory(1);
                    cert.setFileName(jo.getString("name"));
                    cert.setStorageName(jo.getString("url"));
                    cert.setCreateBy(createBy);
                    certs.add(cert);
                }
            }
            if(certs.size() >= 200){
                try {
                    baseDao.insert("employeeMapper.saveEmployeeCert", certs);
                    certs = new ArrayList<>();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
//            System.out.println(employee.getEduCerts());
//            System.out.println(employee.getQuaCerts());
        }
        baseDao.insert("employeeMapper.saveEmployeeCert", certs);

    }


}
